﻿namespace fleetIt.Core
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using System.Xml.Serialization;
    using System.Xml;
    using System.Runtime.Serialization.Formatters.Binary;

    /// <summary>
    /// 
    /// </summary>
    public class Common : IDisposable
    {
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="stream"></param>
        /// <returns></returns>
        public T CreateObject<T>(XmlDocument xmlDocument)
        {
            T result = default(T);
            using (MemoryStream memoryStream = new MemoryStream())
            {
                xmlDocument.Save(memoryStream);
                memoryStream.Seek(0, SeekOrigin.Begin);
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
                result = (T)xmlSerializer.Deserialize(memoryStream);
            }
            return result;
        }

        public void CreateObjectCache(object businessObject, string fileName)
        {
            using (StreamWriter streamWriter = new StreamWriter(fileName))
            {
                BinaryFormatter binaryFormatter = new BinaryFormatter();
                binaryFormatter.Serialize(streamWriter.BaseStream, businessObject);
                binaryFormatter = null;
            }
        }

        public object ReadObjectCache(string fileName)
        {
            using (StreamReader streamReader = new StreamReader(fileName))
            {
                BinaryFormatter binaryFormatter = new BinaryFormatter();
                return binaryFormatter.Deserialize(streamReader.BaseStream);
            }
        }

        /// <summary>
        /// This method returns the output of the SendRequest as Stream.
        /// </summary>
        /// <param name="webResponse">Output of SendRequest method</param>
        /// <returns>Stream as the Result</returns>
        public Stream GetResponseStream(HttpWebResponse webResponse)
        {
            return webResponse.GetResponseStream();
        }

        /// <summary>
        /// This method returns the output of the SendRequest as XmlDocument.
        /// </summary>
        /// <param name="webResponse">Output of SendRequest method</param>
        /// <returns>XmlDocument as the Result</returns>
        public XmlDocument GetResponseXml(HttpWebResponse webResponse)
        {
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.Load(webResponse.GetResponseStream());
            return xmlDocument;
        }

        /// <summary>
        /// This method returns the output of the SendRequest as String.
        /// </summary>
        /// <param name="webResponse">Output of SendRequest method</param>
        /// <returns>String as the Result</returns>
        public string GetResponseString(HttpWebResponse webResponse)
        {
            using (StreamReader streamReader = new StreamReader(webResponse.GetResponseStream()))
            {
                return streamReader.ReadToEnd();
            }
        }

        /// <summary>
        /// This method used to send API requests.
        /// </summary>
        /// <param name="requestMethod">Request methods(Check RequestMethod enum)</param>
        /// <param name="url">Url to Process</param>
        /// <param name="responseFormat">Expected Response format.</param>
        /// <param name="parameters">Parameters required for the request.</param>
        /// <returns>WebResponse</returns>
        public HttpWebResponse SendRequest(RequestMethod requestMethod,
            string url,
            ResponseFormats responseFormat,
            Dictionary<string, string> parameters)
        {
            HttpWebRequest httpWebRequest = null;
            HttpWebResponse httpWebResponse = null;
            int index = 0;
            if (responseFormat != ResponseFormats.none)
            {
                parameters.Add("format", responseFormat.ToString());
            }
            switch (requestMethod)
            {
                case RequestMethod.POST:

                    string data = string.Empty;
                    if (parameters != null)
                    {
                        index = 0;
                        foreach (KeyValuePair<string, string> parameter in parameters)
                        {
                            data += string.Format("{0}{1}={2}", index == 0 ? string.Empty : "&", parameter.Key, parameter.Value);
                            index++;
                        }
                    }
                    httpWebRequest = HttpWebRequest.Create(url) as HttpWebRequest;
                    httpWebRequest.ContentType = "application/x-www-form-urlencoded";
                    httpWebRequest.Method = requestMethod.ToString();
                    using (StreamWriter streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
                    {
                        streamWriter.Write(data);
                    }
                    httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse;
                    break;
                case RequestMethod.GET:
                    string modifiedUrl = string.Empty;
                    if (parameters != null)
                    {
                        index = 0;
                        foreach (KeyValuePair<string, string> parameter in parameters)
                        {
                            modifiedUrl += string.Format("{0}{1}={2}", index == 0 ? "?" : "&", parameter.Key, parameter.Value);
                            index++;
                        }
                    }
                    modifiedUrl = string.Format("{0}{1}", url, modifiedUrl);
                    httpWebRequest = HttpWebRequest.Create(modifiedUrl) as HttpWebRequest;
                    httpWebRequest.Method = requestMethod.ToString();
                    httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse;
                    break;
                default:
                    break;
            }
            return httpWebResponse;
        }


        #region IDisposable Members
        /// <summary>
        /// 
        /// </summary>
        public void Dispose()
        {
            //Do nothing.
        }

        #endregion
    }

    /// <summary>
    /// 
    /// </summary>
    public enum RequestMethod
    {
        POST, GET
    }

    /// <summary>
    /// 
    /// </summary>
    public enum ResponseFormats
    {
        xml, json, rss, atom, txt, none
    }
}
